home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostuf / demoinit.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-07-25  |  8.6 KB  |  538 lines

  1. UNIT DEMOINIT;
  2. {
  3.   THIS UNIT WAS CODED BY BJARKE VIKS0E.
  4.   YOU ARE FREE TO DO WHATEVER YOU WANT WITH THIS PIECE OF CODE.
  5.   E-MAIL ME AT: dat92230@rix02.lyngbyes.dk IN 1994 FOR CHAT AND CODE.
  6.  
  7.   This is it.
  8.   All usefull sub-routines are collected here.
  9.   Look around and you'll probably find something.
  10. }
  11.  
  12. INTERFACE
  13.  
  14. {$S-,F-,B-}
  15.  
  16. uses
  17.     DOS;
  18.  
  19. const
  20.     {screen constants}
  21.     WIDTH = 80;
  22.     HEIGHT = 200;
  23.     SCRSIZE = 65528;
  24.     {assmebler '386 opcode prefixes}
  25.     FS = $64;
  26.     GS = $65;
  27.     LONG = $66;
  28.  
  29. type
  30.     pScreen = ^ScreenType;
  31.     ScreenType = array[0..SCRSIZE] of byte;
  32.  
  33. var
  34.     Key : char;
  35.     ytabel : array[0..240] of word;
  36.     keyhit : array[0..127] of byte;
  37.     retraces : word;
  38.     total_retraces : word;
  39.     {pointer to user-interrupt hook}
  40.     timerproc : procedure;
  41.     {store old interrupt-pointers}
  42.     Int08Save : procedure;
  43.     Int09Save : procedure;
  44.  
  45.  
  46. procedure OpenScreen;
  47. procedure InModeX;
  48. procedure CloseScreen;
  49. procedure ClearWholeScreen;
  50. procedure VBLANK;
  51. procedure VBLANK_QUICK;
  52. procedure Screen_On;
  53. procedure Screen_Off;
  54. procedure SetAddress(a : pointer);
  55. procedure SetHorizOfs(count : byte);
  56. procedure SetRGB(color : integer; r,g,b : byte);
  57. procedure SetBitplanes(planes : byte);
  58. inline(
  59.     $BA/$C4/$03/    {mov    dx,$3C4}
  60.     $58/                {pop    ax}
  61.     $88/$C4/            {mov    ah,al}
  62.     $B0/$02/            {mov    al,$02}
  63.     $EF);                {out    dx,ax}
  64. procedure SetWriteMode(m : byte);
  65. procedure SetLineRepeat(nr:Byte);
  66. procedure CLI; inline($FA);
  67. procedure STI; inline($FB);
  68.  
  69. procedure SetPixel(page : word; x,y : integer; color : byte);
  70.  
  71. procedure SetAllInterrupts;
  72. procedure RestoreAllInterrupts;
  73. procedure SetKbdInterrupt;
  74. procedure RestoreKbdInterrupt;
  75. procedure SetTimerInterrupt;
  76. procedure RestoreTimerInterrupt;
  77.  
  78. function  KeyPressed : boolean;
  79.  
  80. function LongDiv(X: longint; Y: Integer) : Integer;
  81. inline($59/$58/$5A/$F7/$F9);
  82. function LongMul(X, Y : integer) : longint;
  83. inline($5A/$58/$F7/$EA);
  84.  
  85.  
  86.  
  87. (*-----------------------------------------*)
  88.  
  89. IMPLEMENTATION
  90.  
  91. const
  92.     TIMESET = 2610; {2838 / 2610}
  93.     TIMEOUT = 7;
  94.     keymap : string = ' e1234567890-=  QWERTYUIOP[]  ASDFGHJKL;`\  ZXCVBNM,./                                                   ';
  95.  
  96. var
  97.     OldScreenMode : byte;
  98.     OldExitProc : pointer;
  99.  
  100.     SpecialKeys : byte;
  101.     timercount : integer;
  102.  
  103.     KeyInstalled : boolean;
  104.     TimerInstalled : boolean;
  105.  
  106. (*-----------------------------------------*)
  107.  
  108. {$F+}
  109. procedure ScreenExitProc;
  110. begin
  111.   ExitProc:=OldExitProc;
  112.   CloseScreen;
  113. end;
  114. {$F-}
  115.  
  116. procedure OpenScreen; { Setup Tweak-VGA screen }
  117. var
  118.     i : integer;
  119. begin
  120.     for i:=0 to 240 do ytabel[i]:=i*WIDTH;
  121.  
  122.     asm
  123.         mov    ah,$0F                    { Fetch the current videomode }
  124.         int    $10                        { and save it }
  125.         mov    OldScreenMode,al
  126.  
  127.         mov    ax,$13                    { Init 320*200 screen }
  128.         int    $10
  129.  
  130.         cli                                { Setup TWEAK-VGA }
  131.         mov    dx,$3C4
  132.         mov    al,4
  133.         out    dx,al
  134.         inc    dx
  135.         in        al,dx
  136.         and    al,$F7
  137.         or        al,4
  138.         out    dx,al
  139.  
  140.         mov    dx,$3CE
  141.         mov    al,5
  142.         out    dx,al
  143.         inc    dx
  144.         in        al,dx
  145.         and    al,$EF
  146.         out    dx,al
  147.  
  148.         dec    dx
  149.         mov    al,6
  150.         out    dx,al
  151.         inc    dx
  152.         in        al,dx
  153.         and    al,$FD
  154.         out    dx,al
  155.  
  156.         mov    dx,$3D4
  157.         mov    al,$14
  158.         out    dx,al
  159.         inc    dx
  160.         in        al,dx
  161.         and    al,$BF
  162.         out    dx,al
  163.  
  164.         dec    dx
  165.         mov    al,$17
  166.         out    dx,al
  167.         inc    dx
  168.         in        al,dx
  169.         or        al,$40
  170.         out    dx,al
  171.         sti
  172.     end;
  173.  
  174.     OldExitProc:=ExitProc;
  175.     ExitProc:=@ScreenExitProc;
  176. end;
  177.  
  178. procedure CloseScreen;
  179. begin
  180.     asm
  181.         xor    ah,ah    { Set the old videomode }
  182.         mov    al,OldScreenMode
  183.         mov    al,3 {-- overload OldScreenMode and force 80*25-mode}
  184.         int    $10
  185.     end;
  186.     Writeln;
  187.     Writeln('A small piece of code by Bjarke Viksφe...');
  188. end;
  189.  
  190. procedure InModeX;
  191. begin
  192.     CLI;
  193.     Port[$3C2]:=$E3;
  194.     PortW[$3D4]:=$2C11;
  195.     PortW[$3D4]:=$0D06;
  196.     PortW[$3D4]:=$3E07;
  197.     PortW[$3D4]:=$EA10;
  198.     PortW[$3D4]:=$AC11;
  199.     PortW[$3D4]:=$DF12;
  200.     PortW[$3D4]:=$E715;
  201.     PortW[$3D4]:=$0616;
  202.     STI;
  203. end;
  204.  
  205.  
  206. (*-----------------------------------------*)
  207.  
  208. procedure VBLANK; assembler;
  209. asm
  210.     cmp    TimerInstalled,TRUE
  211.     je        @timerinstalled
  212.     mov    dx,3DAh
  213. @vent1:
  214.     in        al,dx
  215.     test    al,8
  216.     jz        @vent1
  217.     cli
  218. @vent2:
  219.     in        al,dx
  220.     test    al,8
  221.     jnz    @vent2
  222.     sti
  223.     jmp    NEAR PTR @done
  224.  
  225. @timerinstalled:
  226.     mov    ax,total_retraces
  227. @vent3:
  228.     cmp    ax,total_retraces
  229.     je        @vent3
  230. @done:
  231. end;
  232.  
  233. procedure VBLANK_QUICK; assembler;
  234. asm
  235.     cmp    TimerInstalled,TRUE
  236.     je        @timerinstalled
  237.     cli
  238.     mov     dx,3DAh
  239. @vent1:
  240.     in      al,dx
  241.     test    al,8
  242.     jz         @vent1
  243.     sti
  244.     jmp    NEAR PTR @done
  245.  
  246. @timerinstalled:
  247.     mov    ax,total_retraces
  248. @vent2:
  249.     cmp    ax,total_retraces
  250.     je        @vent2
  251. @done:
  252. end;
  253.  
  254. procedure SCREEN_OFF; assembler;
  255. asm
  256.     cli
  257.     mov    dx,$3C4
  258.     mov    al,$01
  259.     out    dx,al
  260.     inc    dx
  261.     in        al,dx
  262.     or        al,$20
  263.     out    dx,al
  264.     sti
  265. end;
  266.  
  267. procedure SCREEN_ON; assembler;
  268. asm
  269.     cli
  270.     mov    dx,$3C4
  271.     mov    al,$01
  272.     out    dx,al
  273.     inc    dx
  274.     in        al,dx
  275.     and    al,$DF
  276.     out    dx,al
  277.     sti
  278. end;
  279.  
  280. procedure SetAddress(a : pointer); assembler;
  281. asm
  282.     cli
  283.     mov bx,WORD PTR a
  284.     mov dx,$3d4
  285.     mov al,$c
  286.     mov ah,bh
  287.     out dx,ax
  288.     inc ax
  289.     mov ah,bl
  290.     out dx,ax
  291.     sti
  292. end;
  293.  
  294. procedure SetHorizOfs(count : byte);
  295. var
  296.     i : byte;
  297. begin
  298.     i:=Port[$3DA];
  299.     Port[$3C0]:=$33;
  300.     Port[$3C0]:=Count SHL 1;
  301. end;
  302.  
  303. procedure SetRGB(color : integer; r,g,b : byte); assembler;
  304. asm
  305.     cli
  306.     mov    dx,$3C8
  307.     mov    ax,color
  308.     out    dx,al
  309.     inc    dx
  310.     mov    al,r
  311.     out    dx,al
  312.     mov    al,g
  313.     out    dx,al
  314.     mov    al,b
  315.     out    dx,al
  316.     sti
  317. end;
  318.  
  319.  
  320. procedure SetPixel(page : word; x,y : integer; color : byte); assembler;
  321. asm
  322.     cli
  323.     mov    dx,$3C4
  324.     mov    al,$02
  325.     mov    ah,1
  326.     mov    cx,x
  327.     and    cl,11b
  328.     shl    ah,cl
  329.     out    dx,ax
  330.     sti
  331.  
  332.     mov    es,SEGA000
  333.     mov    bx,y
  334.     add    bx,bx
  335.     mov    di,[OFFSET ytabel+bx]
  336.     add    di,page
  337.     mov    ax,x
  338.     shr    ax,2
  339.     add   di,ax
  340.     mov    al,color
  341.     mov    [es:di],al
  342. end;
  343.  
  344. procedure SetLineRepeat(nr:Byte);
  345. begin
  346.     Port[$3D4]:=9;
  347.     Port[$3D5]:=Port[$3D5] AND $F0+nr;
  348. end;
  349.  
  350. procedure SetWriteMode(m : byte);
  351. begin
  352.     Port[$3CE]:=$05;
  353.     Port[$3CF]:=(Port[$3CF] AND $FC) OR (m AND 3);
  354. end;
  355.  
  356.  
  357. (*-----------------------------------------*)
  358.  
  359.  
  360. procedure ClearWholeScreen; assembler;      { clear most of videomemory }
  361. asm
  362.     cli
  363.     mov    dx,$3C4
  364.     mov    ax,$0F02
  365.     out    dx,ax
  366.     sti
  367.     mov    es,SEGA000
  368.     xor    di,di
  369.     mov    cx,($10000/4)-1
  370.     DB LONG; xor ax,ax
  371.     cld
  372.     rep; DB LONG; stosw;
  373. end;
  374.  
  375. procedure SetTimer(x : word); assembler;
  376. asm
  377.     cli
  378.     mov    al,$36
  379.     out    $43,al
  380.     mov    ax,x
  381.     out    $40,al
  382.     mov    al,ah
  383.     out    $40,al
  384.     sti
  385. end;
  386.  
  387. (*-----------------------------------------*)
  388.  
  389. {$F+}
  390. procedure KbdHandler; interrupt; assembler;
  391. {$F-}
  392. asm
  393.     in        al,$60
  394.     mov    bl,al
  395.  
  396.     in        al,$61
  397.     or        al,$80
  398.     out    $61,al
  399.     and    al,$7F
  400.     out    $61,al
  401.  
  402.     cmp    al,$E0
  403.     jne    @notE0
  404.     add    SpecialKeys,1
  405.     jmp   @done
  406. @notE0:
  407.     cmp    al,$E1
  408.     jne    @notE1
  409.     add    SpecialKeys,2
  410.     jmp    @done
  411. @notE1:
  412.     cmp    SpecialKeys,0
  413.     jz        @nospeckey
  414.     dec    SpecialKeys
  415.     jmp    @done
  416. @nospeckey:
  417.  
  418.     mov    al,bl
  419.     and    bx,$7F
  420.     inc    bx
  421.     cmp    bl,110    {array is only about 110 chars long...}
  422.     ja        @done
  423.     and    al,al
  424.     jns    @pressin
  425.     mov    BYTE PTR [bx+OFFSET keyhit],0
  426.     mov    al,[bx+OFFSET keymap]
  427.     mov    Key,al
  428.     jmp    NEAR PTR @done
  429. @pressin:
  430.     mov    BYTE PTR [bx+OFFSET keyhit],1
  431. @done:
  432.     sti
  433.     mov    al,$20
  434.     out    $20,al
  435. end;
  436.  
  437. {$F+,S-}
  438. procedure TimerHandler; interrupt; assembler;
  439. {$F-}
  440. asm
  441.     inc    timercount
  442.     cmp    timercount,TIMEOUT
  443.     jb        @noretrace
  444.     mov    timercount,0
  445.     mov    dx,$3DA
  446. @vblank:
  447.     in        al,dx
  448.     test    al,$08
  449.     je        @vblank
  450.  
  451.     mov    al,$36
  452.     out    $43,al
  453.     mov    ax,TIMESET
  454.     out    $40,al
  455.     mov    al,ah
  456.     out    $40,al
  457.  
  458. {here comes timer code...}
  459.     inc    retraces
  460.     inc    total_retraces
  461.  
  462.     mov    ax,WORD PTR TimerProc
  463.     or        ax,WORD PTR TimerProc+2
  464.     je        @nouserproc
  465. {$F+}
  466.     call    TimerProc
  467. {$F-}
  468. @nouserproc:
  469.  
  470. @noretrace:
  471.     mov    al,$20
  472.     out    $20,al
  473.     sti
  474. end;
  475.  
  476.  
  477. procedure SetTimerInterrupt;
  478. begin
  479.     retraces:=0;
  480.     total_retraces:=0;
  481.     timercount:=0;
  482.     GetIntVec($08,@Int08Save);
  483.     SetIntVec($08,addr(TimerHandler));
  484.     SetTimer(TIMESET);
  485.     TimerInstalled:=TRUE;
  486. end;
  487.  
  488. procedure RestoreTimerInterrupt;
  489. begin
  490.     SetIntVec($08,@Int08Save);
  491.     SetTimer(0);
  492.     TimerInstalled:=FALSE;
  493. end;
  494.  
  495. procedure SetKbdInterrupt;
  496. var
  497.     i : integer;
  498. begin
  499.     Key:=#0;
  500.     SpecialKeys:=0;
  501.     for i:=1 to sizeof(keyhit) do keyhit[i]:=0;
  502.     GetIntVec($09,@Int09Save);
  503.     SetIntVec($09,addr(KbdHandler));
  504.     KeyInstalled:=TRUE;
  505. end;
  506.  
  507. procedure RestoreKbdInterrupt;
  508. begin
  509.     SetIntVec($09,@Int09Save);
  510.     KeyInstalled:=FALSE;
  511. end;
  512.  
  513. procedure SetAllInterrupts;
  514. begin
  515.     SetTimerInterrupt;
  516.     SetKbdInterrupt;
  517.     Port[$21]:=$5C; {Turns off IRQ 2,3,4, and 6}
  518. end;
  519.  
  520. procedure RestoreAllInterrupts;
  521. begin
  522.     RestoreTimerInterrupt;
  523.     RestoreKbdInterrupt;
  524.     Port[$21]:=0; {Let all IRQ's live}
  525. end;
  526.  
  527. function KeyPressed : boolean;    { test if key has been struck }
  528. begin
  529.     if (KeyInstalled) then KeyPressed:=Key<>#0
  530.     else KeyPressed:=Port[$60]<$80;
  531. end;
  532.  
  533. begin
  534.     TimerProc:=NIL;
  535.     TimerInstalled:=FALSE;
  536.     KeyInstalled:=FALSE;
  537. end.
  538.